package com.gitee.huanminabc.fastboot.load.hook;

import com.gitee.huanminabc.jcommon.multithreading.executor.ThreadFactoryUtil;
import com.gitee.huanminabc.fastboot.context.AppContext;
import com.gitee.huanminabc.fastboot.context.AppContextUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @description:
 * @author: huanmin
 * @create: 2025-04-17 17:37
 **/
@Slf4j
public abstract class AbstractLifecycleHook {
    public <T extends LifecycleHook> void run(List<T> lifecycleHooks) {
        if (lifecycleHooks.isEmpty()) {
            return;
        }
        AppContextUtil.orderSort(lifecycleHooks);
        ThreadPoolExecutor executor = ThreadFactoryUtil.getDefaultExecutor();
        String className =getClass().getSimpleName();
        for (LifecycleHook projectClassLoadFinishHook : lifecycleHooks) {
            executor.execute(() -> {
                try {
                    projectClassLoadFinishHook.run();
                    log.debug("{} load success", projectClassLoadFinishHook.getClass().getSimpleName());
                } catch (Exception e) {
                    log.error("{} load error", className, e);
                }
            });
        }
        log.debug("{} load success", className);
    }

    public <T extends LifecycleHook> void runSync(List<T> lifecycleHooks) {
        if (lifecycleHooks.isEmpty()) {
            return;
        }
        AppContextUtil.orderSort(lifecycleHooks);
        CountDownLatch countDownLatch = new CountDownLatch( lifecycleHooks.size());
        ThreadPoolExecutor executor = ThreadFactoryUtil.getDefaultExecutor();
        String className =getClass().getSimpleName();
        for (LifecycleHook projectClassLoadFinishHook : lifecycleHooks) {
            executor.execute(() -> {
                try {
                    projectClassLoadFinishHook.run();
                    log.debug("{} load success", projectClassLoadFinishHook.getClass().getSimpleName());
                } catch (Exception e) {
                    log.error("{} load error", className, e);
                }finally {
                    countDownLatch.countDown();
                }
            });
        }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            log.error("{} load error", className, e);
        }
        log.debug("{} load success", className);
    }
}
